package com.cgw.game.ui;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.PowerManager;
import android.util.Size;
import android.view.View;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.camera.camera2.Camera2Config;
import androidx.camera.core.Camera;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.CameraX;
import androidx.camera.core.CameraXConfig;
import androidx.camera.core.ImageAnalysis;
import androidx.camera.core.ImageProxy;
import androidx.camera.core.Preview;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.camera.view.PreviewView;
import androidx.core.content.ContextCompat;

import com.cgw.game.R;
import com.cgw.game.utils.ImageProcessing;
import com.cgw.game.view.MyLineChart;
import com.cgw.game.view.MyLineChartRenderer;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.google.common.util.concurrent.ListenableFuture;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;

public class CameraXHeartActivity extends AppCompatActivity implements CameraXConfig.Provider {

    MyLineChart chart;

    private PowerManager.WakeLock wakeLock;
    private TextView text,text1;
    //Android手机预览控件
    //预览设置信息
    private PreviewView previewView;


    private static int gx;
    private static int j;
    private static double flag=1;


    private static int averageIndex = 0;
    private static final int averageArraySize = 4;
    private static final int[] averageArray = new int[averageArraySize];

    private static final AtomicBoolean processing = new AtomicBoolean(false);
    public enum TYPE {
        GREEN, RED
    }
    //设置默认类型
    private static TYPE currentType = TYPE.GREEN;
    //获取当前类型
    public static TYPE getCurrent() {
        return currentType;
    }
    //心跳下标值
    private static int beatsIndex = 0;
    //心跳数组的大小
    private static final int beatsArraySize = 3;
    //心跳数组
    private static final int[] beatsArray = new int[beatsArraySize];
    //心跳脉冲
    private static double beats = 0;
    //开始时间
    private static long startTime = 0;

    private ListenableFuture<ProcessCameraProvider> cameraProviderFuture;
    Camera camera;
    private Handler handler = new Handler();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camerax_heart);
        Toolbar toolbar = findViewById(R.id.toolbar);
        toolbar.setTitle(getIntent().getStringExtra("title"));
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);//左侧添加一个默认的返回图标
        getSupportActionBar().setHomeButtonEnabled(true); //设置返回键可用
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();//返回
            }
        });
        initView();
    }

    @SuppressLint({"InvalidWakeLockTag", "RestrictedApi"})
    private void initView() {
        chart = findViewById(R.id.chart);
        initChart();
        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "DoNotDimScreen");
        previewView = findViewById(R.id.preview);
        text = findViewById(R.id.text);
        text1 =findViewById(R.id.text1);

        cameraProviderFuture = ProcessCameraProvider.getInstance(this);

        ImageAnalysis analysis = new ImageAnalysis.Builder()
                .setTargetResolution(new Size(177,144)).build();
        analysis.setAnalyzer(Executors.newSingleThreadExecutor(), image -> {
            handler.post(() -> analyzer(image));
        });


        previewView.setPreferredImplementationMode(PreviewView.ImplementationMode.SURFACE_VIEW);
        Preview preview = new Preview.Builder().build();
        Preview.SurfaceProvider  surfaceProvider = previewView.createSurfaceProvider();
        preview.setSurfaceProvider(surfaceProvider);

        cameraProviderFuture.addListener(new Runnable() {
            @Override
            public void run() {
                try {
                    ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
                    camera = cameraProvider.bindToLifecycle(
                            CameraXHeartActivity.this,
                    CameraSelector.DEFAULT_BACK_CAMERA,
                            preview,
                            analysis);
                    camera.getCameraControl().enableTorch(true);
                }catch (Exception e){

                }
            }
        }, ContextCompat.getMainExecutor(this));
    }
    /**
    * 初始化图表
    */
    private void initChart() {
        chart.setExtraBottomOffset(5f);
//        chart3Line.getAxisLeft().setDrawGridLines(false);
        chart.setTouchEnabled(true);
        chart.setPinchZoom(false);
        chart.setScaleYEnabled(false);
        chart.setDragEnabled(true);
        chart.setDoubleTapToZoomEnabled(false);
        chart.getViewPortHandler().setMaximumScaleX(5.0f);
        //取消说明
        chart.getLegend().setEnabled(false);
        chart.getDescription().setEnabled(false);
        chart.setNoDataText("暂无数据");
        chart.setVisibleXRangeMaximum(5);

        YAxis leftAxis = chart.getAxisLeft();
        leftAxis.removeAllLimitLines(); // reset all limit lines to avoid overlapping lines
        leftAxis.setTextSize(12f);
        leftAxis.setTextColor(Color.parseColor("#91a2a3"));
//      leftAxis.setValueFormatter(new PercentFormatter());
//        leftAxis.setValueFormatter(new IndexAxisValueFormatter());
        leftAxis.setEnabled(true);
        leftAxis.setGridColor(Color.parseColor("#e3edf2"));
        leftAxis.setDrawAxisLine(true);
        leftAxis.setAxisMinimum(40f);
        leftAxis.setAxisMaximum(220f);
        leftAxis.setLabelCount(5, true);
        chart.getAxisRight().setEnabled(false);

        //横向轴线设置
        XAxis xAxis = chart.getXAxis();
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        xAxis.setTextSize(12f);
        xAxis.setTextColor(Color.parseColor("#91a2a3"));
        xAxis.setEnabled(true);  //是否打开x轴
        xAxis.setDrawGridLines(false);
        xAxis.setAxisMinimum(0f);
        xAxis.setGranularityEnabled(true);
        xAxis.setLabelCount(5, false);
        /*// 转换要显示的标签文本，value值默认是int从0开始
        xAxis.setValueFormatter(new IAxisValueFormatter() {
            @Override
            public String getFormattedValue(float value, AxisBase axis) {
                return famatTime((int) value);
            }
        });*/
        xAxis.setAxisLineColor(Color.parseColor("#e3edf2"));
        //设置为虚线
        xAxis.setDrawAxisLine(true);
    }

    @Override
    public void onResume() {
        super.onResume();
        if(camera!=null){
            camera.getCameraControl().enableTorch(true);
        }
        wakeLock.acquire();

    }

    @Override
    public void onPause() {
        super.onPause();
        if(camera!=null){
            camera.getCameraControl().enableTorch(false);
        }
        wakeLock.release();
    }

    @SuppressLint("RestrictedApi")
    @Override
    protected void onDestroy() {
        super.onDestroy();
        CameraX.unbindAll();
    }



    private void setData(List<Entry> values) {
        if (chart.getRenderer() instanceof MyLineChartRenderer) {
            MyLineChartRenderer renderer = (MyLineChartRenderer) chart.getRenderer();

            int medium = 80;
            int larger = 120;
            int limit = 160;


            int[] colors = new int[4];
            colors[0] = Color.parseColor("#fa7069");
            colors[1] = Color.parseColor("#faa369");
            colors[2] = Color.parseColor("#facd69");
            colors[3] = Color.parseColor("#d3d8dc");

            renderer.setHeartLine(true, medium,larger,limit, colors);
        }
        LineDataSet lineDataSet;
        lineDataSet = new LineDataSet(values, "HOME1");
        lineDataSet.setMode(LineDataSet.Mode.LINEAR);
        lineDataSet.setLabel("Result Scores");
        lineDataSet.setColor(getResources().getColor(R.color.red));
        lineDataSet.setCircleColor(getResources().getColor(R.color.red));
        lineDataSet.setDrawHorizontalHighlightIndicator(false);
        lineDataSet.setHighLightColor(getResources().getColor(R.color.red));
        lineDataSet.enableDashedHighlightLine(10, 10, 0);
        lineDataSet.setFillAlpha(100);
        lineDataSet.setDrawFilled(false);
        lineDataSet.setHighlightLineWidth(1f);
        lineDataSet.setLineWidth(2f);
        lineDataSet.setCircleRadius(3f);
        lineDataSet.setDrawCircleHole(false);
        lineDataSet.setDrawCircles(false);
        lineDataSet.setDrawValues(false);
        LineData lineData = new LineData();
        lineData.addDataSet(lineDataSet);
        chart.setData(lineData);
    }

    public void addEntry(int value) {
        LineData lineData = chart.getLineData();
        if (lineData != null) {
            int count = lineData.getEntryCount();
            lineData.addEntry(new Entry(count,value), 0);
            chart.notifyDataSetChanged();
            chart.invalidate();
            chart.moveViewTo(count, value, YAxis.AxisDependency.LEFT);
        }else {
            List<Entry> values = new ArrayList<>();
            values.add(new Entry(0,value));
            setData(values);
        }
    }

    @NonNull
    @Override
    public CameraXConfig getCameraXConfig() {
        return Camera2Config.defaultConfig();
    }


    @SuppressLint("RestrictedApi")
    private void analyzer(ImageProxy image){
        if (image == null)
            throw new NullPointerException();
        if (!processing.compareAndSet(false, true))
            return;
        byte[] data;
        try {
            data = ImageProcessing.getBytesFromImageAsType(image);
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }
        int width = image.getWidth();
        int height = image.getHeight();
        //图像处理
        int imgAvg = ImageProcessing.decodeYUV420SPtoRedAvg(data.clone(),height,width);
        gx=imgAvg;
//            text1.setText("平均像素值是"+String.valueOf(imgAvg));
        //像素平均值imgAvg,日志
        //Log.i(TAG, "imgAvg=" + imgAvg);
        if (imgAvg == 0 || imgAvg == 255) {
            processing.set(false);
            return;
        }
        //计算平均值
        int averageArrayAvg = 0;
        int averageArrayCnt = 0;
        for (int i = 0; i < averageArray.length; i++) {
            if (averageArray[i] > 0) {
                averageArrayAvg += averageArray[i];
                averageArrayCnt++;
            }
        }
        //计算平均值
        int rollingAverage = (averageArrayCnt > 0)?(averageArrayAvg/averageArrayCnt):0;
        TYPE newType = currentType;
        if (imgAvg < rollingAverage) {
            newType = TYPE.RED;
            if (newType != currentType) {
                beats++;
                flag=0;
                text1.setText("脉冲数是"+String.valueOf(beats));
                //Log.e(TAG, "BEAT!! beats=" + beats);
            }
        } else if (imgAvg > rollingAverage) {
            newType = TYPE.GREEN;
        }

        if (averageIndex == averageArraySize)
            averageIndex = 0;
        averageArray[averageIndex] = imgAvg;
        averageIndex++;

        // Transitioned from one state to another to the same
        if (newType != currentType) {
            currentType = newType;
            //image.postInvalidate();
        }
        //获取系统结束时间（ms）
        long endTime = System.currentTimeMillis();
        double totalTimeInSecs = (endTime - startTime) / 1000d;
        if (totalTimeInSecs >= 2) {
            double bps = (beats / totalTimeInSecs);
            int dpm = (int) (bps * 60d);
            if (dpm < 30 || dpm > 180||imgAvg<200) {
                //获取系统开始时间（ms）
                startTime = System.currentTimeMillis();
                //beats心跳总数
                beats = 0;
                processing.set(false);
                return;
            }
            //Log.e(TAG, "totalTimeInSecs=" + totalTimeInSecs + " beats="+ beats);
            if (beatsIndex == beatsArraySize)
                beatsIndex = 0;
            beatsArray[beatsIndex] = dpm;
            beatsIndex++;
            int beatsArrayAvg = 0;
            int beatsArrayCnt = 0;
            for (int i = 0; i < beatsArray.length; i++) {
                if (beatsArray[i] > 0) {
                    beatsArrayAvg += beatsArray[i];
                    beatsArrayCnt++;
                }
            }
            int beatsAvg = (beatsArrayAvg / beatsArrayCnt);
            text.setText("您的的心率是"+String.valueOf(beatsAvg)+"  zhi:"+String.valueOf(beatsArray.length)
                    +"    "+String.valueOf(beatsIndex)+"    "+String.valueOf(beatsArrayAvg)+"    "+String.valueOf(beatsArrayCnt));
            //获取系统时间（ms）
            addEntry(beatsAvg);
            startTime = System.currentTimeMillis();
            beats = 0;
        }
        processing.set(false);
    }


}
